<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { ElTree, ElButton, ElInput, ElTooltip } from 'element-plus'
import { Search, Download, Refresh } from '@element-plus/icons-vue'

interface Props {
  jsonData: any
}

const props = defineProps<Props>()

// 搜索关键字
const searchKeyword = ref('')

// 过滤后的数据
const filteredData = computed(() => {
  if (!searchKeyword.value || !props.jsonData) return props.jsonData
  
  // 简单实现搜索功能，实际项目中可能需要更复杂的搜索逻辑
  const search = (obj: any): any => {
    if (typeof obj !== 'object' || obj === null) {
      return JSON.stringify(obj).toLowerCase().includes(searchKeyword.value.toLowerCase()) ? obj : null
    }
    
    if (Array.isArray(obj)) {
      const result = obj.map(search).filter(Boolean)
      return result.length ? result : null
    }
    
    const result: Record<string, any> = {}
    let hasMatch = false
    
    for (const key in obj) {
      if (key.toLowerCase().includes(searchKeyword.value.toLowerCase())) {
        result[key] = obj[key]
        hasMatch = true
      } else {
        const value = search(obj[key])
        if (value !== null) {
          result[key] = value
          hasMatch = true
        }
      }
    }
    
    return hasMatch ? result : null
  }
  
  return search(props.jsonData)
})

// 将JSON数据转换为树形结构
const treeData = computed(() => {
  if (!filteredData.value) return []
  return convertToTreeData(filteredData.value, 'root')
})

// 转换函数
const convertToTreeData = (data: any, key: string): any[] => {
  if (data === null) return [{ label: 'null', key }]
  
  if (typeof data !== 'object') {
    return [{
      label: `${key}: ${data}`,
      key,
      value: data,
      isLeaf: true
    }]
  }
  
  if (Array.isArray(data)) {
    return [{
      label: `${key} [${data.length}]`,
      key,
      children: data.flatMap((item, index) => 
        convertToTreeData(item, `${key}[${index}]`)
      )
    }]
  }
  
  const keys = Object.keys(data)
  return [{
    label: `${key} {${keys.length}}`,
    key,
    children: keys.flatMap(k => 
      convertToTreeData(data[k], k)
    )
  }]
}

// 下载JSON数据
const downloadJson = () => {
  if (!props.jsonData) return
  
  const dataStr = JSON.stringify(props.jsonData, null, 2)
  const dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr)
  
  const exportFileDefaultName = 'data.json'
  
  const linkElement = document.createElement('a')
  linkElement.setAttribute('href', dataUri)
  linkElement.setAttribute('download', exportFileDefaultName)
  linkElement.click()
}

// 刷新视图
const refreshView = () => {
  searchKeyword.value = ''
}
</script>

<template>
  <div class="json-viewer">
    <div class="viewer-header">
      <h3>JSON 查看器</h3>
      <div class="viewer-tools">
        <el-input
          v-model="searchKeyword"
          placeholder="搜索JSON..."
          :prefix-icon="Search"
          clearable
        />
        <el-tooltip content="刷新视图">
          <el-button :icon="Refresh" circle @click="refreshView" />
        </el-tooltip>
        <el-tooltip content="下载JSON">
          <el-button :icon="Download" circle @click="downloadJson" />
        </el-tooltip>
      </div>
    </div>
    
    <div class="tree-container">
      <el-tree
        v-if="treeData.length > 0"
        :data="treeData"
        :props="{ children: 'children', label: 'label' }"
        node-key="key"
        default-expand-all
      />
      <div v-else class="no-data">无数据可显示</div>
    </div>
  </div>
</template>

<style scoped>
.json-viewer {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.viewer-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.viewer-header h3 {
  margin: 0;
  color: #e5eaf3;
}

.viewer-tools {
  display: flex;
  gap: 8px;
  align-items: center;
}

.tree-container {
  flex: 1;
  overflow: auto;
  background-color: #2a2a2a;
  border-radius: 4px;
  padding: 12px;
}

.no-data {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  color: #909399;
}

:deep(.el-tree) {
  background-color: transparent;
  color: #e5eaf3;
}

:deep(.el-tree-node__content) {
  background-color: transparent;
}

:deep(.el-tree-node:focus > .el-tree-node__content) {
  background-color: #283142;
}
</style>